﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.IO;
using PdfSharp.Pdf;
using System.Diagnostics;
using System.Windows.Markup;
using Business.Cdc;
using DAO.Cdc;
using CdcBusiness;
using Manageo;

namespace Cdc
{
    /// <summary>
    /// Interaction logic for View.xaml
    /// </summary>
    public partial class View : Manageo.INotifierUI
    {
        private Boolean onlyNotReported = false;
        private ObservableRangeCollection<FileDb> listToShow = null;

        public delegate void addLineDelegate(FileDb i);
        addLineDelegate addLineDel;

        public View()
        {
            InitializeComponent();
            bw.DoWork += new System.ComponentModel.DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

            addLineDel = new addLineDelegate(addLine);
            
        }


        private void addLine(FileDb line)
        {
            this.listToShow.Add(line);
        }

        public ObservableRangeCollection<FileDb> ListToShow
        {
            get
            {
                try
                {
                    if (listToShow == null)
                    {
                        this.listToShow =
                            new ObservableRangeCollection<FileDb>(CdcFilesDAO.getFilesDb(onlyNotReported));
                    }
                    return listToShow;
                }
                catch (Exception e)
                {
                    MessageBox.Show("impossible de récupérer les fichiers\n\n" + e, "Error !!!", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                return null;
            }
        }

        public Boolean OnlyNotReported
        {
            get
            {
                return onlyNotReported;
            }
            set
            {
                onlyNotReported = value;
                if (value) 
                    dockManager.AutoHideGroups.Clear();
            }
        }

        public void refresh()
        {
            this.listToShow.Clear();
            List<FileDb> files = CdcFilesDAO.getFilesDb(onlyNotReported);
            foreach(FileDb file in files) 
            {
                this.listToShow.Add(file);
            }            
        }

        private void viewFile(object sender, MouseButtonEventArgs e)
        {
            try
            {
                int rowHandle = this.gridControl1.View.GetRowHandleByMouseEventArgs(e);
                if (rowHandle != DevExpress.Wpf.Grid.GridControl.InvalidRowHandle)
                {
                    if (!this.gridControl1.IsGroupRowHandle(rowHandle))
                    {
                        String tempDir = Environment.GetEnvironmentVariable("TEMP");

                        FileDb fileDb = (FileDb)this.gridControl1.GetRow(rowHandle);
                        MemoryStream ms = new MemoryStream(CdcFilesDAO.getFile(fileDb.Id));
                        PdfDocument pdf = CdcBusiness.PdfDocumentGenerator.getFileToSave(ms);
                        String fileName = tempDir + @"\" + fileDb.Title + ".pdf";
                        pdf.Save(fileName);
                        Process.Start(fileName);
                    }
                }
            }
            catch (IOException ex)
            {
                MessageBox.Show("impossible de voir le fichier \n\n" + ex, "Error !!!", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void keyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                DevExpress.Wpf.Grid.TableView view = (DevExpress.Wpf.Grid.TableView)sender;
                if (view.ActiveEditor == null || !view.ActiveEditor.IsEditorActive)
                    DeleteRow(view.FocusedRowHandle);
            }
        }

        private void DeleteRow(int rowHandle)
        {
            int listIndex = this.gridControl1.GetRowListIndex(rowHandle);
            ObservableCollection<FileDb> list =
                (ObservableCollection<FileDb>)this.gridControl1.DataSource;
            if (listIndex >= 0)
            {
                FileDb line = list[listIndex];
                try
                {
                    if (!onlyNotReported)
                        CdcFilesDAO.deleteFile(line.Id);
                    list.RemoveAt(listIndex);
                }
                catch (Exception e)
                {
                    MessageBox.Show("error while deleting compta line (id = " + line.Id + ")\n" + e.StackTrace, "ERROR !!!", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
        #region Import
        private PdfDocument pdfDoc = null;
        System.ComponentModel.BackgroundWorker bw = new System.ComponentModel.BackgroundWorker();

        void bw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            loadFiles((string)e.Argument);
        }

        void bw_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message + "\n\n" + e.Error.StackTrace, "ERREUR !!!", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        
        public void loadFiles(String pathCsv)
        {
            FileStream inStream = new FileStream(pathCsv, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            MemoryStream storeStream = new MemoryStream();

            storeStream.SetLength(inStream.Length);
            inStream.Read(storeStream.GetBuffer(), 0, (int)inStream.Length);
            storeStream.Flush();
            inStream.Close();
            StreamReader rdr = new StreamReader(storeStream, System.Text.Encoding.Default);

            int i = 0,j=0;
            while (!rdr.EndOfStream)
            {
                rdr.ReadLine();
                i++;
            }
            double lineNumbers = i-1;

            OnBegin(null);

            string line, fileStr, path, filePath,  title, type, subject, fromStr = null, toStr = null;
            DateTime date;
            Stream fs = null;
            Boolean reported;
            FileDb file;
            int from = -1, to = -1;

            rdr.BaseStream.Position = 0;
            // on supprime les headers !
            if (!rdr.EndOfStream)
            {
                line = rdr.ReadLine();
            }
            i = 0;
            int value;
            // on lit les données
            try
            {
                while (!rdr.EndOfStream)
                {
                    j = 0;
                    line = rdr.ReadLine();
                    string[] data = line.Split(';');                    
                    path = data[j++];
                    fileStr = data[j++];
                    title = data[j++];
                    subject = data[j++];
                    date = DateTime.Parse(data[j++]);
                    reported = "1".Equals(data[j++]);
                    filePath = (String.IsNullOrEmpty(path)) ? fileStr : path + @"\" + fileStr;
                    if (data.Length > 6)
                    {
                        fromStr = data[j++];
                        toStr = data[j++];
                    }
                    if (String.IsNullOrEmpty(fromStr) && String.IsNullOrEmpty(toStr))
                    {
                        fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    }
                    else
                    {
                        j++;
                        from = Int32.Parse(fromStr);
                        j++;
                        to = Int32.Parse(toStr);
                        PdfDocument pdfDoc = PdfDocumentGenerator.selectFile(filePath);
                        pdfDoc = PdfDocumentGenerator.getFile(pdfDoc, from, to);
                        fs = new MemoryStream();
                        pdfDoc.Save(fs, false);
                    }
                    file = new FileDb();
                    file.Subject = subject;
                    file.Title = title;
                    file.Date = date;
                    file.Reported = reported;
                    file.Id = CdcFilesDAO.InsertData(fs, file);
                    this.Dispatcher.Invoke(addLineDel, System.Windows.Threading.DispatcherPriority.Normal, file);
                    
                    value = (int)(((++i) / lineNumbers) * 100.0);
                    OnChanged(new Manageo.NotifyEventArgs(value, "import des fichiers en cours..."));
                }
            }
            catch (Exception e)
            {
                throw new ImportException("Problème lors de l'import : \nException pendant l'analyse des données à la ligne " + (i + 2) + " - colonne " + j + "\n\n" + e.Message);
            }
            finally
            {
                OnEnded(null);
            }
        }

        private void add(object sender, RoutedEventArgs e)
        {
            try
            {
                pdfDoc = PdfDocumentGenerator.getFile(pdfDoc, (int)FromTb.Value, (int)ToTb.Value);

                MemoryStream ms = new MemoryStream();
                pdfDoc.Save(ms, false);
                FileDb file = new FileDb();
                file.Reported = false;
                file.Subject = SubjectCb.Text;
                file.Title = TitleTb.Text;
                file.Date = dateCh.DateTime;
                file.Id = CdcFilesDAO.InsertData(ms, file);
                this.listToShow.Add(file);
                ms.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erreur pendant l'ajout du pdf !\n\n"+ex.Message, "ERREUR !!!", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void selectFile(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.DefaultExt = ".pdf";
            dlg.Filter = "PDF documents (.pdf)|*.pdf";

            // Display OpenFileDialog by calling ShowDialog method
            Nullable<bool> result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox
            if (result == true)
            {
                // Open document
                string filename = dlg.FileName;
                FilePathTb.Text = filename;
                pdfDoc = PdfDocumentGenerator.selectFile(filename);
                this.FromTb.IsEnabled = true;
                this.ToTb.IsEnabled = true;
                this.FromTb.MaxValue = pdfDoc.PageCount;
                this.ToTb.MaxValue = pdfDoc.PageCount;
                this.ToTb.Value = pdfDoc.PageCount+1;
                this.FromTb.Value = 1;
            }
        }

        private void loadFiles(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.DefaultExt = ".csv";
            dlg.Filter = "CSV documents (.csv)|*.csv";

            // Display OpenFileDialog by calling ShowDialog method
            Nullable<bool> result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox
            if (result == true && !String.IsNullOrEmpty(dlg.FileName))
            {
                this.csvFileTb.Text = dlg.FileName;
            }
        }

        private void import(object sender, RoutedEventArgs e)
        {
            if (!String.IsNullOrEmpty(this.csvFileTb.Text))
                bw.RunWorkerAsync(this.csvFileTb.Text);
            else 
                MessageBox.Show("vous devez d'abord sélectionner un fichier !", "ERREUR !!!", MessageBoxButton.OK, MessageBoxImage.Error);
        }
        #endregion

    }

    //public class RecordCheckConverter : MarkupExtension, IValueConverter
    //{
    //    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    //    {
    //        switch (value.ToString())
    //        {
    //            case "TVA": return "LightGoldenrodYellow";
    //            case "Facture": return "#01B0F0";
    //            case "Internet": return "Red";
    //            case "Repas": return "#96CA2D";
    //            case "Report": return "#00EE08";
    //            case "Portable": return "LightBlue";
    //            case "Others": return "#B16F2D";
    //            case "Extrait Bancaire": return "Yellow";
    //            case "Transport": return "Magenta";
    //            default: return null;
    //        }
    //    }

    //    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    //    {
    //        return value;
    //    }

    //    public override object ProvideValue(IServiceProvider serviceProvider)
    //    {
    //        return this;
    //    }
    //}


    public class SizeDisplayTextConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value != null)
            {
                int bitSize = (int)value;
                if (bitSize > 1000)
                {
                    bitSize = bitSize / 1024;
                    if (bitSize > 1000)
                    {
                        bitSize = bitSize / 1024;
                        return bitSize + " Mb";
                    }
                    else
                    {
                        return bitSize + " Kb";
                    }
                }
                else
                {
                    return bitSize + " b";
                }
            }
            return null;
        }

        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;
        }
    }

}
